package com.sharelords.biz.creator.compile;

import com.sun.tools.javac.api.JavacTool;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.util.logging.Logger;

/**
 * @author 千古龙少
 * @Description: class编译器生成器
 * @date 2020年6月14日 下午7:35:26
 */
public class CompilerCreator {

    private static final Logger logger = Logger.getLogger("CompilerCreator");

    private static JavaCompiler compiler;

    private CompilerCreator() {
    }

    /**
     * 懒加载模式获取编译器
     *
     * @return JavaCompiler
     */
    public static JavaCompiler getCompiler() {
        if (compiler == null) {
            loadCompiler();
        }

        return compiler;
    }

    /**
     * 载入编译器
     */
    private static synchronized void loadCompiler() {
        try {
            compiler = getJavaCompiler();
            if (compiler != null) {
                logger.info("java编译器获取成功。");
            }
        } catch (Exception e) {
            logger.warning("JavaCompiler编译器获取失败，请检查系统中是否安装了jdk，且maven仓库中引入了tools.jar文件！");
        }
    }

    /**
     * 获取编译器
     *
     * @return JavaCompiler java编译器
     * @throws Exception
     */
    private static JavaCompiler getJavaCompiler() throws Exception {
        // 如果能获取到，直接返回（jdk环境）
        compiler = ToolProvider.getSystemJavaCompiler();
        if (compiler != null) {
            return compiler;
        }

        // 如果不能获取到，说明是jre环境，从系统安装的tools.jar中获取
        logger.info("java本地编译器获取失败，尝试从tools.jar中获取java编译器。");
        return getJavaCompilerByLocation();
    }

    /**
     * 从tools.jar中获取编译器
     *
     * @return JavaCompiler java编译器
     * @throws Exception
     */
    private static JavaCompiler getJavaCompilerByLocation() throws Exception {
        return JavacTool.class.asSubclass(JavaCompiler.class).getConstructor().newInstance();
    }
}
